#pragma once

// Copyright (c) 2010 Manuel Peinado Gallego <manuel.peinado@gmail.com>
// Distributed under the MIT license

// Shader.h : interface of the Shader class
//

#include <iostream>
#include <string>
#include "Selectable.h"
#include "gl.h"
class ShaderProgram;

#define MPG_VERBOSE_SHADERS 1


class Shader : public Selectable
{
public:

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    Shader(GLenum type, std::istream& is);

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


    GLuint getId() const;

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    void setProgram(ShaderProgram* program);

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    void setFileName(const std::string& newFileName);

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    
    // Replaces the code that was read by the constructor
    void setCode(std::istream& is);

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    std::string getCode() const;

    // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    bool compiles() const;

private:

    // Only a shader program can compile directly
    friend ShaderProgram;
    void compile() const;
    mutable bool m_codeCompiled;

    // Implementation helper used internally by SetCode
    void setCodeImpl(std::istream& is);
    
    // The owner of this shader (all shaders must have one)
    ShaderProgram* m_program;

    // Not set if this shader came from a stream
    std::string m_fileName;

    // As returned by glCreateShader
    GLuint m_id;

    // The code for this shader
    std::string m_code;

    // GL_VERTEX_SHADER or GL_FRAGMENT_SHADER
    GLenum m_type;  
};

